#include <sys/epoll.h>


#include "channel.h"
#include "eventloop.h"
#include "logger.h"

//表示事件
const int Channel::kNoneEvent = 0;
const int Channel::kReadEvent = EPOLLIN | EPOLLPRI;
const int Channel::kWriteEvent = EPOLLOUT;


Channel::Channel(EventLoop* loop, int fd)
    : loop_(loop)
    , fd_(fd)
    , events_(0)
    , revents_(0)
    , index_(-1)
    , tied_(false){
        //update();
    }


Channel::~Channel() {}

//  使用 弱指针 绑定某个obj
void Channel::tie(const std::shared_ptr<void> & obj){
    tie_ = obj;
    tied_ = true;
}


void Channel::update(){
    // ToDO 
    loop_->updateChannel(this);
}

void Channel::remove(){
    // ToDO 
    loop_->removeChannel(this);
}


void Channel::handlerEvent(TimeStamp receiveTime){
    if(!tie_.expired()){
        std::shared_ptr<void> guard = tie_.lock();
        if(guard){
            handleEventWithGuard(receiveTime);
        }
    }else{
        handleEventWithGuard(receiveTime);
    }
}

void Channel::handleEventWithGuard(TimeStamp receiveTime){
    LOG_INFO("channel handleEvent revents:%d\n", revents_);
    if((revents_ & EPOLLHUP) && !(revents_ & EPOLLIN)){
        if(closeCallBack_){
            closeCallBack_();
        }
    }

    if(revents_ & EPOLLERR){
        if(errorCallBack_){
            errorCallBack_();
        }
    }

    if(isReading()){
        if(readCallBack_){
            readCallBack_(receiveTime);
        }
    }

    if(isWriting()){
        if(writeCallBack_){
            writeCallBack_();
        }
    }
}